using GGPhysics;
using UnityEngine;

public class GGPWorld : MonoBehaviour
{
	public enum UpdateMode
	{
		FixedUpdate = 0,
		Update = 1,
		GGUpdate = 2,
		None = 3
	}

	public PhysicsWorld world;

	public bool startSymOnAwake;

	public UpdateMode updateMode;

	public PhysicsBodyDefinition defaultBodyDefinitions;

	public bool printCollisionStats;

	public float ggUpdateNumberPerSec = 10f;

	public float currentTime { get; protected set; }

	public float ggTimestep
	{
		get
		{
			return 1f / ggUpdateNumberPerSec;
		}
	}

	public void Awake()
	{
		if (startSymOnAwake)
		{
			InitializeWorldFromChildren();
		}
	}

	public void InitializeWorldFromChildren()
	{
		world.physicsBodies.Clear();
		InitializeWorldFromChildren(base.transform);
	}

	protected void InitializeWorldFromChildren(Transform transform)
	{
		foreach (Transform item in transform)
		{
			if (item.gameObject.activeSelf)
			{
				GGPBody component = item.GetComponent<GGPBody>();
				GGPShape component2 = item.GetComponent<GGPShape>();
				PhysicsBody physicsBody = null;
				if ((bool)component)
				{
					physicsBody = component.GetBodyWithShape();
				}
				else if (component2 != null)
				{
					physicsBody = new PhysicsBody();
					physicsBody.type = PhysicsBody.PhysicsBodyType.StaticBody;
					physicsBody.shape = component2.shape;
					physicsBody.tag = item.tag;
					physicsBody.physicsDefinitions = defaultBodyDefinitions;
				}
				if (physicsBody != null)
				{
					Transform posTrans = ((!(component != null) || !component.positionUpdateTransform) ? item : component.positionUpdateTransform);
					Transform rotTrans = ((!(component != null) || !component.rotationUpdateTransform) ? item : component.rotationUpdateTransform);
					physicsBody.SetUnityTransform(posTrans, rotTrans);
					world.AddPhysicsBody(physicsBody);
				}
				if (component2 as GGPCompositeLineCollider == null)
				{
					InitializeWorldFromChildren(item);
				}
			}
		}
	}

	private void FixedUpdate()
	{
		if (updateMode == UpdateMode.FixedUpdate)
		{
			GGUpdate(Time.fixedDeltaTime);
		}
	}

	public float UpdateWithTimestep(float deltaTime)
	{
		currentTime += deltaTime;
		if (currentTime >= ggTimestep)
		{
			int num = Mathf.Max(1, Mathf.FloorToInt(currentTime / ggTimestep));
			for (int i = 0; i < num; i++)
			{
				GGUpdate(ggTimestep);
			}
			currentTime -= ggTimestep * (float)num;
		}
		return currentTime / ggTimestep;
	}

	private void Update()
	{
		if (updateMode == UpdateMode.Update)
		{
			GGUpdate(Time.deltaTime);
		}
		else if (updateMode != UpdateMode.GGUpdate)
		{
		}
	}

	public void GGUpdate(float deltaTime)
	{
		if (printCollisionStats)
		{
			CollisionDetection.stats.Clear();
		}
		world.Step(deltaTime);
		if (printCollisionStats)
		{
			CollisionDetection.CollisionStats stats = CollisionDetection.stats;
			Debug.Log(string.Format("BallBall - aabb={0},check={1} BallLine - aabb={2},check={3} - Sweep(items:{4} checks:{5} potential:{6} sortIter:{7})", stats.ballBallAABBFail, stats.ballBallCheck, stats.ballLineAABBFail, stats.ballLineCheck, stats.sweepItems, stats.sweepChecks, stats.sweepPotentialCollisions, stats.sortIterations));
		}
	}
}
